Skip to content

Add OuterExtensions encoding for TLS ECH client#10306

Merged
dgarske merged 3 commits intowolfSSL:masterfrom
sebastian-carpenter:tls-ech-client-oe
May 7, 2026
Merged

Add OuterExtensions encoding for TLS ECH client#10306
dgarske merged 3 commits intowolfSSL:masterfrom
sebastian-carpenter:tls-ech-client-oe

Conversation

@sebastian-carpenter
Copy link
Copy Markdown
Contributor

@sebastian-carpenter sebastian-carpenter commented Apr 24, 2026

Summary

Adds client-side ECH ech_outer_extensions encoding (RFC 9849 §5.1). The inner ClientHello now encodes duplicate extensions so they can be expanded on the server-side later. This can shrink the HPKE-sealed payload significantly.

Changes

  • TLSX_ECH_IsEncodeable — gate list of non-compressible extensions (SNI, ECH, ALPN, PSK, early_data).
  • TLSX_ECH_BuildOuterExtensions — walks ssl->extensions then ssl->ctx->extensions and emits the ech_outer_extensions block. Capped at 127 extensions.
  • TLSX_GetSizeWithEch / TLSX_WriteWithEch — size and write the encoded inner as [ech_outer_extensions][non-encodables] (what is sent on the wire), and the expanded inner as [encodables][non-encodables] (what is hashed for the transcript).
  • TLSX_ECH_ExpandOuterExtensions — fix extension-length rewrite when the outer carries a session id.
  • SendTls13ClientHello — computes both inner sizes, hashes the expanded form via EchHashHelloInner, then rewrites the buffer in encoded form for HPKE seal. ech->innerCount is set explicitly after TLSX_FinalizeEch rather than as a side effect of hashing.
  • EchHashHelloInner — always receives the expanded body; no longer strips paddingLen + Nt.
  • CI (openssl-ech.sh / openssl-ech.yml) — adds --pqc argument and runs with SecP384r1MLKEM1024 so the inner exceeds openssl's ECH limit (if OuterExtensions was not used). Also added the --hrr argument.

Testing

  • OpenSSL-server ↔ wolfSSL-client interop with an ML-KEM hybrid key share (CI). Previously would fail from the ECH extension being too big for openSSL.
  • HRR interop testing. OpenSSL expects ECH at the end of the HRR -> update the write order.

Checklist

  • added tests
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

@sebastian-carpenter sebastian-carpenter self-assigned this Apr 24, 2026
Copilot AI review requested due to automatic review settings April 24, 2026 18:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds client-side ECH ech_outer_extensions encoding support (RFC 9849 §5.1) to shrink the sealed ClientHelloInner, with new APIs to enable/disable at CTX/SSL scope and CI interop updates.

Changes:

  • Implement OuterExtensions encoding/expansion in the TLS extensions write/size paths and ClientHelloInner hashing/sealing.
  • Add CTX/SSL options + public setters to opt out of the encoding (enabled by default).
  • Extend CI OpenSSL ECH interop to run with an ML-KEM hybrid group and new --pqc plumbing.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
wolfssl/ssl.h Exposes new public APIs to toggle ECH OuterExtensions encoding.
wolfssl/internal.h Adds new ECH/writeEncoded flag and CTX/SSL option bits for encoding control.
src/ssl_ech.c Implements the new CTX/SSL setters controlling the encoding behavior.
src/internal.c Propagates CTX encoding-disable setting into per-SSL options at init.
src/tls.c Adds OuterExtensions encoding selection and fixes expansion length rewrite for session-id cases.
src/tls13.c Separates “expanded” vs “encoded” inner sizes and hashes expanded form before sealing encoded form.
tests/api.c Adds coverage for disabling encoding via CTX and SSL APIs.
.github/workflows/openssl-ech.yml Enables ML-KEM and runs OpenSSL↔wolfSSL interop using a PQC hybrid group.
.github/scripts/openssl-ech.sh Adds --pqc CLI support and forwards it to the wolfSSL client.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/tls13.c Outdated
Comment thread src/tls13.c Outdated
Comment thread wolfssl/internal.h Outdated
Comment thread src/tls.c Outdated
Comment thread src/tls.c
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 24, 2026

MemBrowse Memory Report

No memory changes detected for:

Comment thread wolfssl/ssl.h Outdated
@sebastian-carpenter
Copy link
Copy Markdown
Contributor Author

sebastian-carpenter commented May 6, 2026

Jenkins retest this please.

@sebastian-carpenter sebastian-carpenter removed their assignment May 7, 2026
Copy link
Copy Markdown
Member

@dgarske dgarske left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accepting as-is. Thanks. I made a future todo note about converting that bit to a WC_BITFIELD for next bit that gets added.

Comment thread wolfssl/internal.h
@dgarske dgarske merged commit e78418d into wolfSSL:master May 7, 2026
447 of 448 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants